/*
 * Copyright 2012 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell.date;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.datepicker.client.DatePicker;

import finbudgettable.client.ui.grid.Utils;
import finbudgettable.client.ui.grid.cell.date.filter.Filters;
import finbudgettable.client.ui.grid.column.FilterPanel;
import finbudgettable.client.ui.grid.filter.FieldFilter;
import finbudgettable.client.ui.grid.filter.Filter;
import finbudgettable.client.ui.grid.filter.FilterChangeEvent;
import finbudgettable.client.ui.grid.filter.FilterChangeHandler;

import java.util.Date;

public class DateFilterPanel extends VerticalPanel implements FilterPanel {

    public class DatePanel extends PopupPanel {

        public DatePanel() {
            super(true, true);
        }

        @Override
        protected void onPreviewNativeEvent(Event.NativePreviewEvent event) {
            if (Event.ONKEYUP == event.getTypeInt()) {
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) {
                    hide();
                }
            }
        }
    }

    private final ListBox listBox;
    private final Anchor anchor;
    private Date value;
    private final DatePanel datePanel;
    private final Filters filters;

    public DateFilterPanel(Filters filters) {
        this.filters = filters;
        Label filterLabel = new Label(Strings.INSTANCE.filter());

        Label valueLabel = new Label(Strings.INSTANCE.value());

        listBox = new ListBox();
        for (String op : filters.getOperations().keySet()) {
            listBox.addItem(op);
        }

        datePanel = new DatePanel();
        DatePicker datePicker = new DatePicker();
        datePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                setValue(event.getValue());
                datePanel.hide();
            }
        });
        datePanel.add(datePicker);


        anchor = new Anchor(Strings.INSTANCE.emptyDate());

        final Button applyButton = new Button(Strings.INSTANCE.applyFilter());
        applyButton.setStyleName(Utils.blueButton);
        applyButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Date value = getValue();
                if (value != null) {
                    String op = listBox.getValue(listBox.getSelectedIndex());
                    fireEvent(new FilterChangeEvent(createFilter(op)));
                }
            }
        });

        anchor.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                datePanel.setPopupPosition(anchor.getAbsoluteLeft(), anchor.getAbsoluteTop());
                datePanel.show();
            }
        });

        Grid grid = new Grid(3, 2);
        grid.setStyleName(DateCell.RESOURCES.style().bDateFilterPanel());
        grid.setWidget(0, 0, filterLabel);
        grid.setWidget(0, 1, listBox);
        grid.setWidget(1, 0, valueLabel);
        grid.setWidget(1, 1, anchor);
        grid.setWidget(2, 1, applyButton);

        add(grid);
    }

    public Date getValue() {
        return value;
    }

    protected Filter createFilter(String op) {
        return filters.createFilter(this, op);
    }

    @SuppressWarnings("unchecked")
	@Override
    public void setFilter(Filter filter) {
        if (filter != null && filter instanceof FieldFilter<?>) {
            Filters.FilterPresenter presenter = filters.getPresenter(filter.getClass());
            if (presenter != null) {
                presenter.show(this, (FieldFilter<Date>) filter);
                return;
            }
        }
        anchor.setText(Strings.INSTANCE.emptyDate());
        listBox.setSelectedIndex(0);
    }

    @Override
    public void addFilterChangeHandler(FilterChangeHandler handler) {
        addHandler(handler, FilterChangeEvent.TYPE);
    }

    public boolean setOperationByName(String op) {
        for (int i = 0; i < listBox.getItemCount(); i++) {
            if (op.equals(listBox.getValue(i))) {
                listBox.setSelectedIndex(i);
                return true;
            }
        }
        return false;
    }

    public void setValue(Date date) {
        value = date;
        anchor.setText(StringDateAdapter.INSTANCE.getValue(date));
    }

    public void setFilterCaption(String caption){
        anchor.setText(caption);
    }
}
